import os
import subprocess
import psutil
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
                            QPushButton, QLabel, QLineEdit, QTableWidget, QTableWidgetItem, 
                            QTabWidget, QSplitter, QFrame, QMessageBox, QHeaderView, QComboBox, 
                            QGroupBox, QGridLayout, QCheckBox, QTextEdit, QProgressBar)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, pyqtSlot, QTimer
from PyQt5.QtGui import QFont, QColor, QPalette, QIcon
import tqsdk
from datetime import datetime, timedelta
import time
import json
import sqlite3
import logging
import sys

# 仅在Windows系统导入win32相关库
if os.name == 'nt':
    import win32gui
    import win32con
    import win32process

# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class TqAccount:
    def __init__(self, parent=None):
        self.parent = parent
        self.api = None
        self.connected = False
        self.account_info = {}
        self.capital = 0.0

    def connect(self, account, password):
        try:
            self.api = tqsdk.TqApi(tqsdk.TqAccount("H海通期货", account, password))
            self.connected = True
            self.get_account_info()
            logger.info("账户连接成功")
            return True
        except Exception as e:
            logger.error(f"账户连接失败: {str(e)}")
            return False

    def get_account_info(self):
        if not self.connected or not self.api:
            return
        try:
            self.account_info = self.api.get_account()
            self.capital = self.account_info.get('available', 0.0)
            if self.parent:
                self.parent.update_capital_signal.emit(self.capital)
        except Exception as e:
            logger.error(f"获取账户信息失败: {str(e)}")

    def disconnect(self):
        if self.connected and self.api:
            self.api.close()
            self.connected = False
            logger.info("账户已断开连接")

class WorkerThread(QThread):
    update_signal = pyqtSignal(str)
    capital_signal = pyqtSignal(float)
    error_signal = pyqtSignal(str)

    def __init__(self, account, password, parent=None):
        super().__init__(parent)
        self.parent = parent
        self.account = account
        self.password = password
        self.running = False
        self.tq_account = TqAccount(self)
        self.tq_account.update_capital_signal.connect(self.on_capital_updated)
        self.process = None

    def run(self):
        self.running = True
        if not self.tq_account.connect(self.account, self.password):
            self.error_signal.emit("账户连接失败，请检查账号密码")
            return

        # 启动外部程序
        exe_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "auto_stp10_stable04_01.exe")
        if not os.path.exists(exe_path):
            self.error_signal.emit(f"未找到程序文件: {exe_path}")
            self.tq_account.disconnect()
            return

        try:
            # 根据操作系统设置不同的启动参数
            if os.name == 'nt':
                # Windows系统使用创建标志
                self.process = subprocess.Popen(exe_path, creationflags=subprocess.CREATE_NO_WINDOW)
            else:
                # Linux系统直接启动
                self.process = subprocess.Popen(exe_path)
            logger.info(f"外部程序启动成功，PID: {self.process.pid}")
            self.update_signal.emit(f"外部程序启动成功，PID: {self.process.pid}")

            # 最小化外部程序窗口（仅Windows）
            self.minimize_exe_window()

            # 定期更新资金信息
            while self.running and self.process.poll() is None:
                self.tq_account.get_account_info()
                time.sleep(5)

            # 检查程序是否异常退出
            if self.process.poll() is not None:
                self.error_signal.emit(f"外部程序已退出，退出码: {self.process.returncode}")

        except Exception as e:
            self.error_signal.emit(f"程序启动失败: {str(e)}")
        finally:
            self.tq_account.disconnect()
            self.running = False

    def stop(self):
        self.running = False
        # 终止外部程序
        if self.process and self.process.poll() is None:
            try:
                # 使用psutil终止进程及其子进程
                parent = psutil.Process(self.process.pid)
                for child in parent.children(recursive=True):
                    child.terminate()
                parent.terminate()
                logger.info("外部程序已终止")
            except Exception as e:
                logger.error(f"终止外部程序失败: {str(e)}")
        self.wait()

    def minimize_exe_window(self):
        # 仅在Windows系统执行窗口最小化操作
        if os.name != 'nt':
            return

        def callback(hwnd, extra):
            if win32gui.IsWindowVisible(hwnd):
                _, process_id = win32process.GetWindowThreadProcessId(hwnd)
                if process_id == self.process.pid:
                    win32gui.ShowWindow(hwnd, win32con.SW_MINIMIZE)
                    return False
            return True

        win32gui.EnumWindows(callback, None)

    @pyqtSlot(float)
    def on_capital_updated(self, capital):
        self.capital_signal.emit(capital)

class MainWindow(QMainWindow):
    update_capital_signal = pyqtSignal(float)

    def __init__(self):
        super().__init__()
        self.setWindowTitle("交易系统 v4.0")
        self.setGeometry(100, 100, 1200, 800)
        self.worker_thread = None
        self.init_ui()
        self.setup_connections()

    def init_ui(self):
        # 创建主部件和布局
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)

        # 创建顶部状态栏
        self.status_bar = QLabel("就绪")
        main_layout.addWidget(self.status_bar)

        # 创建标签页控件
        self.tab_widget = QTabWidget()
        main_layout.addWidget(self.tab_widget)

        # 初始化各个页面
        self._init_capital_ui()
        self._init_order_ui()
        self._init_product_management_ui()
        self._init_strategy_ui()
        self._init_global_settings_ui()
        self._init_help_ui()

        # 创建底部控制区
        control_layout = QHBoxLayout()
        self.start_btn = QPushButton("启动交易")
        self.stop_btn = QPushButton("停止交易")
        self.stop_btn.setEnabled(False)

        control_layout.addWidget(self.start_btn)
        control_layout.addWidget(self.stop_btn)
        main_layout.addLayout(control_layout)

    def _init_capital_ui(self):
        capital_widget = QWidget()
        layout = QVBoxLayout(capital_widget)

        # 资金信息展示
        self.capital_label = QLabel("当前可用资金: 0.00")
        self.capital_label.setFont(QFont("SimHei", 14, QFont.Bold))
        layout.addWidget(self.capital_label, alignment=Qt.AlignCenter)

        # 添加资金历史图表（此处简化处理）
        history_frame = QFrame()
        history_frame.setFrameShape(QFrame.StyledPanel)
        history_layout = QVBoxLayout(history_frame)
        history_layout.addWidget(QLabel("资金历史走势（图表区域）"))
        layout.addWidget(history_frame)

        self.tab_widget.addTab(capital_widget, "资金管理")

    def _init_order_ui(self):
        order_widget = QWidget()
        layout = QVBoxLayout(order_widget)

        # 订单表格
        self.order_table = QTableWidget()
        self.order_table.setColumnCount(6)
        self.order_table.setHorizontalHeaderLabels(["订单号", "品种", "方向", "价格", "数量", "状态"])
        self.order_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        layout.addWidget(self.order_table)

        # 订单操作区
        order_ops_layout = QHBoxLayout()
        self.product_combo = QComboBox()
        self.direction_combo = QComboBox()
        self.direction_combo.addItems(["买入", "卖出"])
        self.price_edit = QLineEdit()
        self.price_edit.setPlaceholderText("价格")
        self.volume_edit = QLineEdit()
        self.volume_edit.setPlaceholderText("数量")
        self.submit_btn = QPushButton("提交订单")

        order_ops_layout.addWidget(QLabel("品种:"))
        order_ops_layout.addWidget(self.product_combo)
        order_ops_layout.addWidget(QLabel("方向:"))
        order_ops_layout.addWidget(self.direction_combo)
        order_ops_layout.addWidget(QLabel("价格:"))
        order_ops_layout.addWidget(self.price_edit)
        order_ops_layout.addWidget(QLabel("数量:"))
        order_ops_layout.addWidget(self.volume_edit)
        order_ops_layout.addWidget(self.submit_btn)

        layout.addLayout(order_ops_layout)
        self.tab_widget.addTab(order_widget, "订单管理")

    def _init_product_management_ui(self):
        product_widget = QWidget()
        layout = QVBoxLayout(product_widget)

        # 品种表格
        self.product_table = QTableWidget()
        self.product_table.setColumnCount(4)
        self.product_table.setHorizontalHeaderLabels(["品种代码", "品种名称", "合约乘数", "最小变动价位"])
        self.product_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        layout.addWidget(self.product_table)

        # 品种操作按钮
        btn_layout = QHBoxLayout()
        self.add_product_btn = QPushButton("添加品种")
        self.edit_product_btn = QPushButton("编辑品种")
        self.delete_product_btn = QPushButton("删除品种")
        self.save_product_btn = QPushButton("保存品种")

        btn_layout.addWidget(self.add_product_btn)
        btn_layout.addWidget(self.edit_product_btn)
        btn_layout.addWidget(self.delete_product_btn)
        btn_layout.addWidget(self.save_product_btn)
        layout.addLayout(btn_layout)

        self.tab_widget.addTab(product_widget, "品种管理")
        self._refresh_product_table()

    def _init_strategy_ui(self):
        strategy_widget = QWidget()
        layout = QVBoxLayout(strategy_widget)

        # 策略表格
        self.strategy_table = QTableWidget()
        self.strategy_table.setColumnCount(4)
        self.strategy_table.setHorizontalHeaderLabels(["策略名称", "品种", "开仓状态", "参数设置"])
        self.strategy_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        layout.addWidget(self.strategy_table)

        # 策略控制
        ctrl_layout = QHBoxLayout()
        self.toggle_strategy_btn = QPushButton("切换策略状态")
        self.edit_strategy_btn = QPushButton("编辑策略参数")
        ctrl_layout.addWidget(self.toggle_strategy_btn)
        ctrl_layout.addWidget(self.edit_strategy_btn)
        layout.addLayout(ctrl_layout)

        self.tab_widget.addTab(strategy_widget, "策略管理")
        self._refresh_strategy_table()

    def _init_global_settings_ui(self):
        settings_widget = QWidget()
        layout = QVBoxLayout(settings_widget)

        # 全局配置表格
        self.config_table = QTableWidget()
        self.config_table.setColumnCount(2)
        self.config_table.setHorizontalHeaderLabels(["配置项", "值"])
        self.config_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        layout.addWidget(self.config_table)

        # 配置操作
        config_ops_layout = QHBoxLayout()
        self.save_config_btn = QPushButton("保存配置")
        config_ops_layout.addWidget(self.save_config_btn)
        layout.addLayout(config_ops_layout)

        self.tab_widget.addTab(settings_widget, "全局设置")
        self._refresh_config_table()

    def _init_help_ui(self):
        help_widget = QWidget()
        layout = QVBoxLayout(help_widget)

        # 帮助信息
        help_text = QTextEdit()
        help_text.setReadOnly(True)
        help_text.setHtml("""
        <h3>使用帮助</h3>
        <p>1. 资金管理页面：查看当前资金和历史走势</p>
        <p>2. 订单管理页面：查看和提交订单</p>
        <p>3. 品种管理页面：管理可交易品种</p>
        <p>4. 策略管理页面：管理交易策略</p>
        <p>5. 全局设置页面：配置系统参数</p>
        """)
        layout.addWidget(help_text)

        self.tab_widget.addTab(help_widget, "帮助中心")

    def setup_connections(self):
        # 按钮连接
        self.start_btn.clicked.connect(self.on_start_clicked)
        self.stop_btn.clicked.connect(self.on_stop_clicked)
        self.submit_btn.clicked.connect(self.submit_order)
        self.add_product_btn.clicked.connect(self._show_add_product_dialog)
        self.edit_product_btn.clicked.connect(self._show_edit_product_dialog)
        self.delete_product_btn.clicked.connect(self._delete_selected_product)
        self.save_product_btn.clicked.connect(self._save_product_changes)
        self.toggle_strategy_btn.clicked.connect(self.toggle_strategy_open)
        self.edit_strategy_btn.clicked.connect(self._edit_strategy_params)
        self.save_config_btn.clicked.connect(self._save_configs)

        # 表格按键事件
        self.product_table.keyPressEvent = self.handle_product_table_key_event
        self.strategy_table.keyPressEvent = self.handle_strategy_table_key_event

    def on_start_clicked(self):
        # 获取账户密码（此处简化处理，实际应用需添加输入框）
        account = "default_account"
        password = "default_password"

        self.worker_thread = WorkerThread(account, password, self)
        self.worker_thread.update_signal.connect(self.update_status)
        self.worker_thread.capital_signal.connect(self.update_capital)
        self.worker_thread.error_signal.connect(self.show_error)
        self.worker_thread.start()

        self.start_btn.setEnabled(False)
        self.stop_btn.setEnabled(True)
        self.update_status("交易系统启动中...")

    def on_stop_clicked(self):
        if self.worker_thread:
            self.worker_thread.stop()
            self.worker_thread = None

        self.start_btn.setEnabled(True)
        self.stop_btn.setEnabled(False)
        self.update_status("交易系统已停止")

    def submit_order(self):
        # 简化的订单提交逻辑
        product = self.product_combo.currentText()
        direction = self.direction_combo.currentText()
        price = self.price_edit.text()
        volume = self.volume_edit.text()

        if not all([product, direction, price, volume]):
            QMessageBox.warning(self, "输入错误", "请填写完整订单信息")
            return

        # 添加订单到表格
        row = self.order_table.rowCount()
        self.order_table.insertRow(row)
        self.order_table.setItem(row, 0, QTableWidgetItem(f"ORD{row+1000}"))
        self.order_table.setItem(row, 1, QTableWidgetItem(product))
        self.order_table.setItem(row, 2, QTableWidgetItem(direction))
        self.order_table.setItem(row, 3, QTableWidgetItem(price))
        self.order_table.setItem(row, 4, QTableWidgetItem(volume))
        self.order_table.setItem(row, 5, QTableWidgetItem("提交中"))

        self.update_status(f"订单提交成功: {product} {direction} {volume}手 @ {price}")

    def _refresh_product_table(self):
        # 模拟刷新品种表格
        self.product_table.setRowCount(0)
        # 实际应用中应从数据库加载
        sample_products = [
            ("RB2110", "螺纹钢2110", 10, 1),
            ("HC2110", "热卷2110", 10, 1),
            ("I2110", "铁矿石2110", 100, 0.5),
            ("J2110", "焦炭2110", 10, 0.5)
        ]

        for i, (code, name, multiplier, min_price) in enumerate(sample_products):
            self.product_table.insertRow(i)
            self.product_table.setItem(i, 0, QTableWidgetItem(code))
            self.product_table.setItem(i, 1, QTableWidgetItem(name))
            self.product_table.setItem(i, 2, QTableWidgetItem(str(multiplier)))
            self.product_table.setItem(i, 3, QTableWidgetItem(str(min_price)))
            self.product_combo.addItem(code)

    def _refresh_strategy_table(self):
        # 模拟刷新策略表格
        self.strategy_table.setRowCount(0)
        # 实际应用中应从数据库加载
        sample_strategies = [
            ("均线交叉策略", "RB2110", True, "参数..."),
            ("突破策略", "HC2110", False, "参数..."),
            ("趋势跟踪策略", "I2110", True, "参数...")
        ]

        for i, (name, product, is_open, params) in enumerate(sample_strategies):
            self.strategy_table.insertRow(i)
            self.strategy_table.setItem(i, 0, QTableWidgetItem(name))
            self.strategy_table.setItem(i, 1, QTableWidgetItem(product))
            status = "开仓中" if is_open else "已关闭"
            self.strategy_table.setItem(i, 2, QTableWidgetItem(status))
            self.strategy_table.setItem(i, 3, QTableWidgetItem(params))

    def _refresh_config_table(self):
        # 模拟刷新配置表格
        self.config_table.setRowCount(0)
        # 实际应用中应从配置文件加载
        sample_configs = [
            ("自动止损比例", "0.02"),
            ("最大持仓手数", "10"),
            ("交易时间限制", "09:00-15:00"),
            ("日志级别", "INFO")
        ]

        for i, (config, value) in enumerate(sample_configs):
            self.config_table.insertRow(i)
            self.config_table.setItem(i, 0, QTableWidgetItem(config))
            self.config_table.setItem(i, 1, QTableWidgetItem(value))

    def _show_add_product_dialog(self):
        # 简化的添加品种对话框
        QMessageBox.information(self, "提示", "打开添加品种对话框（实际应用需实现）")
        # 实际应用中应弹出对话框并保存到数据库

    def _show_edit_product_dialog(self):
        # 简化的编辑品种对话框
        selected = self.product_table.currentRow()
        if selected < 0:
            QMessageBox.warning(self, "警告", "请先选择要编辑的品种")
            return
        QMessageBox.information(self, "提示", "打开编辑品种对话框（实际应用需实现）")

    def _delete_selected_product(self):
        selected = self.product_table.currentRow()
        if selected < 0:
            QMessageBox.warning(self, "警告", "请先选择要删除的品种")
            return

        if QMessageBox.question(self, "确认", "确定要删除选中品种吗？") == QMessageBox.Yes:
            self.product_table.removeRow(selected)
            self._save_product_changes()

    def _save_product_changes(self):
        # 保存品种变更（实际应用需保存到数据库）
        QMessageBox.information(self, "成功", "品种信息已保存")

    def toggle_strategy_open(self):
        selected = self.strategy_table.currentRow()
        if selected < 0:
            QMessageBox.warning(self, "警告", "请先选择要操作的策略")
            return

        # 切换开仓状态
        current_status = self.strategy_table.item(selected, 2).text()
        new_status = "已关闭" if current_status == "开仓中" else "开仓中"
        self.strategy_table.item(selected, 2).setText(new_status)
        self.update_status(f"策略状态已切换为: {new_status}")

    def _edit_strategy_params(self):
        selected = self.strategy_table.currentRow()
        if selected < 0:
            QMessageBox.warning(self, "警告", "请先选择要编辑的策略")
            return
        QMessageBox.information(self, "提示", "打开策略参数编辑对话框（实际应用需实现）")

    def _save_configs(self):
        # 保存配置变更（实际应用需保存到配置文件）
        QMessageBox.information(self, "成功", "全局配置已保存")

    def handle_product_table_key_event(self, event):
        # 处理表格按键事件
        if event.key() == Qt.Key_Delete:
            self._delete_selected_product()
        else:
            super(QTableWidget, self.product_table).keyPressEvent(event)

    def handle_strategy_table_key_event(self, event):
        # 处理策略表格按键事件
        if event.key() == Qt.Key_Space:
            self.toggle_strategy_open()
        else:
            super(QTableWidget, self.strategy_table).keyPressEvent(event)

    @pyqtSlot(str)
    def update_status(self, message):
        self.status_bar.setText(message)
        logger.info(message)

    @pyqtSlot(float)
    def update_capital(self, capital):
        self.capital_label.setText(f"当前可用资金: {capital:.2f}")

    @pyqtSlot(str)
    def show_error(self, message):
        QMessageBox.critical(self, "错误", message)
        self.update_status(f"错误: {message}")

    @pyqtSlot(float)
    def on_capital_updated(self, capital):
        self.capital_signal.emit(capital)

    def closeEvent(self, event):
        # 窗口关闭时停止线程
        if self.worker_thread:
            self.worker_thread.stop()
        event.accept()

if __name__ == "__main__":
    # 设置中文字体支持
    font = QFont("SimHei")
    app = QApplication(sys.argv)
    app.setFont(font)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())